Conversation
bd94959 to
928c7f5
Compare
928c7f5 to
5625aa6
Compare
| _Size __n1 = std::ranges::size(__r1); | ||
| _Size __n2 = std::ranges::size(__r2); | ||
| return !(__n1 < __n2) && oneapi::dpl::ranges::equal(std::forward<_ExecutionPolicy>(__exec), | ||
| std::views::all(__r1) | std::views::drop(__n1 - __n2), |
There was a problem hiding this comment.
Is views::all deliberately used instead of ranges::ref_view, which is shown in the standard? If yes, what is the motivation?
There was a problem hiding this comment.
According to the standard,
Given a subexpression E, the expression
views::all(E)is expression-equivalent to:
- decay-copy(E) if the decayed type of E models
view.- Otherwise,
ref_view{E}if that expression is well-formed.- Otherwise,
owning_view{E}.
In our case, ref_view{__r1} is valid (it can be formally proven based on the definition of the ref_view constructor), so the 3rd option is never considered. And that I think makes the use of views::all both appropriate and beneficial, as it avoids creating an extra indirection in case __r1 is already a view, and it "simplifies" the expression syntax via "pipelining".
There was a problem hiding this comment.
views::all is almost always good enough, in my opinion unless you explicitly want a view with reference-like semantics or specifically want owning semantics.
Also, Alexey is right in making a point that all_t does not create any indirection, when possible. This technique is used in std::ranges deduction guides all over the place.
The implementations of
ranges::starts_/ends_withredirect tomismatchandequalrespectively, as described in the C++ standard.